/**
 *  State 状态模式
 * 定义：允许一个对象在其内部状态改变时改变它的行为。从而使对象看起来似乎修改了其行为。
 * 要点：
a)State模式将所有与一个特定状态相关的行为都放入一个State的子类对象中，在对象状态切换时，切换相应的对象；
  但同时维持State的接口，这样实现了具体操作与状态转换之间的解耦。
b)为不同的状态引入不同的对象使得状态转换变得更加明确，而且可以保证不会出现状态不一致的情况，
  因为转换是原子性的——即要么彻底转换过来，要么不转换。
c)如果State对象没有实例变量，那么各个上下文可以共享同一个State对象，从而节省对象开销。
 */
// 状态模式 -------------
class State {
  writeProgram(w) {

  }
}
class ForenoonState extends State {
  writeProgram(w) {
    console.log(w)
    if (w.hour < 12) {
      console.log(`当前时间：${w.hour}点，上午工作，精神百倍。`);
    } else {
      w.setState(new NoonState());
      w.writeProgram();
    }
  }
}
class NoonState extends State {
  writeProgram(w) {
    if (w.hour < 14) {
      console.log(`当前时间：${w.hour}点，中午工作，犯困。`);
    } else {
      w.setState(new AfternoonState());
      w.writeProgram();
    }
  }
}
class AfternoonState extends State {
  writeProgram(w) {
    if (w.hour < 18) {
      console.log(`当前时间：${w.hour}点，下午工作，状态不错。`);
    } else {
      w.setState(new ResetState());
      w.writeProgram();
    }
  }
}
class ResetState extends State {
  writeProgram(w) {
    w.isFinished = true;
    console.log(`当前时间：${w.hour}点，下班了，结束工作。`);
  }
}

class Work {
  constructor() {
    this.currentState = new ForenoonState()
    this.isFinished = false
    this.hour = 0
  }

  setState(state) {
    this.currentState = state;
  }

  writeProgram() {
    this.currentState.writeProgram(this);
  }
}

let w = new Work();
w.hour = 9;
w.writeProgram();
w.hour = 13;
w.writeProgram();
w.hour = 17;
w.writeProgram();
w.hour = 9;
w.writeProgram();